#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopgis/djangoproject/include', '/opt/coopgis/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
import COOPGIS_Ajax, COOPGIS_GPS, COOPGIS_Misc, COOPGIS_ReportLab, COOPGIS_String, COOPGIS_Update
import os, csv, shutil, datetime, time, reportlab, djangoproject.settings, random
from django.contrib.gis.db import models
from django.contrib.gis.geos import *
from django.http import HttpResponse
from django.contrib import admin
from django.template import Context, loader
import djangoproject.settings
import _mysql as mysql
from models import *
from django import forms
import django



def index(request):
    if request.user.is_anonymous():
        LoginStatus="You are not currently logged in."
    else:
        LoginStatus="Welcome to COOPGIS, " + request.user.username + '.'
    ServerIndicator=djangoproject.settings.COOPGISServerIndicator
    #if(not ServerIndicator):
    #    os.system('sudo -u apachescript sudo mkdir /var/www/music')
    #    os.system('sudo -u apachescript sudo cp /opt/coopgis/media/music/* /var/www/music/')
    #    os.system('sudo -u apachescript sudo cp -R /opt/coopgis/scripts/openlayers/* /var/www/openlayers/')
    #    os.system('sudo -u apachescript sudo chmod -R 777 /var/www/openlayers/')
    MusicIndicator=bool('Music' in str(request.user.groups.all())) 
    if(MusicIndicator):  
       if(random.randint(0, 100) > -5):  #Disable Music for now
           MusicIndicator=False
    try:
        os.system("sudo -u apachescript sudo chmod 777 " + djangoproject.settings.COOPGISStartupMusicDestinationPathName) 
        os.system("sudo -u apachescript sudo cp " + djangoproject.settings.COOPGISStartupMusicSourceFileName + " " + djangoproject.settings.COOPGISStartupMusicDestinationFileName)
        os.system("sudo -u apachescript sudo chmod 777 " + djangoproject.settings.COOPGISStartupMusicDestinationFileName)
    except:
        pass
    if ServerIndicator:
        IPAddress=djangoproject.settings.COOPGISServerIPAddress
    elif djangoproject.settings.COOPGISInVirtualMachineIndicator:
        IPAddress='192.168.206.10'
    else:
        IPAddress='localhost'
    LastUpdateDateTime=COOPGIS_Update.GetLastUpdateDateTime()
    CommandsNotOnServerThatShouldBe=Command.objects.all().exclude(CommandResidesOnServerIndicator=True).filter(CommandCreateDateTime__lte=LastUpdateDateTime)
    CommandsNotOnServerThatShouldBeCount=CommandsNotOnServerThatShouldBe.count()
    #a=Command.objects.all().order_by('id')
    #a[0].Process()
    #a = Command.objects.filter(id=72)[0]
    #b = a.GetCSVString()
    if(CommandsNotOnServerThatShouldBe.count()):
        WarningIndicator=True
    else:
        WarningIndicator=False
    t = loader.get_template('/opt/coopgis/djangoproject/templates/mainmenu.html')
    c = Context({'LoginStatus': LoginStatus, 'ServerIndicator': ServerIndicator, 'MusicIndicator': MusicIndicator,
                 'IPAddress': IPAddress, 'WarningIndicator':  WarningIndicator, 
                 'CommandsNotOnServerThatShouldBeCount':  CommandsNotOnServerThatShouldBeCount})
    return HttpResponse(t.render(c))

def Login(request):
    if request.method == 'POST':
        username = request.POST['UserName']
        password = request.POST['Password']
        user=django.contrib.auth.authenticate(username=username, password=password)
        if(user is not None):
            if(user.is_active):
                django.contrib.auth.login(request, user)
                return(index(request))
            else:
                InvalidStatus='This account is disabled'
        else:
            InvalidStatus='Invalid username or password'
        loginForm=LoginForm(request.POST)
    else:
        loginForm=LoginForm()
        InvalidStatus='Enter your username and password'
    t=loader.get_template('/opt/coopgis/djangoproject/templates/login.html')
    c=Context({'loginForm': loginForm, 'InvalidStatus': InvalidStatus})
    return HttpResponse(t.render(c))


def Logout(request):
    django.contrib.auth.logout(request) 
    t=loader.get_template('/opt/coopgis/djangoproject/templates/logout.html')
    c=Context({})
    return HttpResponse(t.render(c))


def ChangePassword(request):
    if request.method == 'POST':
        FormDictionary=BuildChangePasswordForm()
        changePasswordForm=COOPGIS_Misc.DynForm()
        changePasswordForm.setFields(FormDictionary)
        changePasswordForm.setData(request.POST)
    else:
        FormDictionary=BuildChangePasswordForm()
        changePasswordForm=COOPGIS_Misc.DynForm()
        changePasswordForm.setFields(FormDictionary)
        changePasswordForm.data={}
    PasswordChangeMessage=''  #PasswordChangeMessage is also used as a Boolean to see if there is not a reason to change the password
    #Do not let a user that is not logged in attempt to change their password
    if request.user.is_anonymous():
        LoginStatus="You are not currently logged in.  Please login through the Main Menu."
        PasswordChangeMessage='You need to login before you can change your password.'
    else:
        LoginStatus='Welcome to the Password Change Utility, ' + str(request.user.username)
        UserName=request.user.username
    try:
        OldPassword=changePasswordForm.data['OldPassword']
    except:
        OldPassword=''
    try:
        NewPassword=changePasswordForm.data['NewPassword']
    except:
        NewPassword=''
    try:
        NewPasswordVerify=changePasswordForm.data['NewPasswordVerify']
    except:
        NewPasswordVerify=''
    try:
        User=django.contrib.auth.authenticate(username=UserName, password=OldPassword)
    except:
        User=None
    if not User and not PasswordChangeMessage:
        PasswordChangeMessage='Your old password did not match.  Try again.'
    else:
        if(NewPassword <> NewPasswordVerify) and not PasswordChangeMessage:
            PasswordChangeMessage='Your new passwords did not match each other.  Try again.'
        if(len(NewPassword) < 6) and not PasswordChangeMessage:
            PasswordChangeMessage='Your new password needs to be at least 6 characters long.  Try again.'
        #If here, ready to reset the password:
        if(not PasswordChangeMessage):
            User.set_password(NewPassword)
            User.save()
            PasswordChangeMessage='Your new password has been changed.'   
    t=loader.get_template('/opt/coopgis/djangoproject/templates/changepassword.html')
    c=Context({'changePasswordForm': changePasswordForm, 'LoginStatus': LoginStatus, 'PasswordChangeMessage': PasswordChangeMessage})
    return HttpResponse(t.render(c))

def Shape(request):
    #if(djangoproject.settings.COOPGISServerIndicator):   #enabled on server...
    #    return index(request)  #This view only works on a client machine    
    os.system('sudo -u apachescript sudo /opt/coopgis/scripts/CreateSymbologyShapeFiles')
    t = loader.get_template('/opt/coopgis/djangoproject/templates/shape.html')
    c = Context({})
    return HttpResponse(t.render(c))

def SystemSummary(request):
    Poles=str(Assembly.objects.filter(CompatibleUnit__PoleIndicator__exact=True).count())
    Meters=str(Assembly.objects.filter(CompatibleUnit__MeterIndicator__exact=True).count())
    TotalVaults=Assembly.objects.filter(CompatibleUnit__VaultIndicator__exact=True).count()
    PadMountTransformers=Assembly.objects.filter(CompatibleUnit__TransformerIndicator=True).filter(CompatibleUnit__NormallyUndergroundIndicator=True).count()    
    VaultsToSubtract=0
    Vaults=Assembly.objects.filter(CompatibleUnit__VaultIndicator__exact=True)
    for i in Vaults:
        if(Assembly.objects.filter(Station=i.Station).filter(CompatibleUnit__PoleIndicator=True)):
            VaultsToSubtract = VaultsToSubtract + 1
    Vaults=str(TotalVaults-VaultsToSubtract)
    SMOSubstations=[200, 400, 600, 800, 1100]
    SDOSubstations=[500, 1000, 1200, 1300]
    RDOSubstations=[300, 700, 900]
    AllSubstations=SMOSubstations + SDOSubstations + RDOSubstations
    SMOPoleTotal, SMOMeterTotal, SMOVaultTotal, SMOPadMountTransformers = GetSubstationsPoleTotal(SMOSubstations)
    SDOPoleTotal, SDOMeterTotal, SDOVaultTotal, SDOPadMountTransformers = GetSubstationsPoleTotal(SDOSubstations)
    RDOPoleTotal, RDOMeterTotal, RDOVaultTotal, RDOPadMountTransformers = GetSubstationsPoleTotal(RDOSubstations)
    UnknownPoleTotal, UnknownMeterTotal, UnknownVaultTotal, UnknownPadMountTransformers = GetSubstationsPoleTotal(AllSubstations, Include=False)
    t=loader.get_template('/opt/coopgis/djangoproject/templates/systemsummary.html')
    c=Context({'Poles': Poles, 'Meters': Meters, 'Vaults': Vaults, 'PadMountTransformers': PadMountTransformers,
               'SMOPole': SMOPoleTotal, 'SMOMeter': SMOMeterTotal, 'SMOVault': SMOVaultTotal, 'SMOPadMountTransformers': SMOPadMountTransformers,
               'SDOPole': SDOPoleTotal, 'SDOMeter': SDOMeterTotal, 'SDOVault': SDOVaultTotal, 'SDOPadMountTransformers': SDOPadMountTransformers,
               'RDOPole': RDOPoleTotal, 'RDOMeter': RDOMeterTotal, 'RDOVault': RDOVaultTotal, 'RDOPadMountTransformers': RDOPadMountTransformers,
               'UnknownPole': UnknownPoleTotal, 'UnknownMeter': UnknownMeterTotal, 'UnknownVault': UnknownVaultTotal, 'UnknownPadMountTransformers': UnknownPadMountTransformers})
    return HttpResponse(t.render(c))   

def GetSubstationsPoleTotal(SubstationNumbers, Include=True):
    TotalPoles=0
    TotalMeters=0
    VaultsTotal=0
    TotalPadMountTransformers=0
    if(not Include):
        Poles=Assembly.objects.filter(CompatibleUnit__PoleIndicator=True)
        Meters=Assembly.objects.filter(CompatibleUnit__MeterIndicator=True)
        Vaults=Assembly.objects.filter(CompatibleUnit__VaultIndicator=True)
        PadMountTransformers=Assembly.objects.filter(CompatibleUnit__TransformerIndicator=True).filter(CompatibleUnit__NormallyUndergroundIndicator=True)
    for substation in SubstationNumbers:
        LowNumber=substation
        HighNumber=substation + 99
        if(Include):
            Poles=Assembly.objects.filter(CompatibleUnit__PoleIndicator__exact=True).filter(CircuitNumber__gte=LowNumber).filter(CircuitNumber__lte=HighNumber).count()
            TotalPoles=TotalPoles + Poles
        else:
            Poles=Poles.exclude(CircuitNumber__gte=LowNumber, CircuitNumber__lte=HighNumber)
        if(Include):
            Meters=Assembly.objects.filter(CompatibleUnit__MeterIndicator__exact=True).filter(CircuitNumber__gte=LowNumber).filter(CircuitNumber__lte=HighNumber).count()
            TotalMeters=TotalMeters + Meters
        else:
            Meters=Meters.exclude(CircuitNumber__gte=LowNumber, CircuitNumber__lte=HighNumber)
        if(Include):
            TotalVaults=Assembly.objects.filter(CompatibleUnit__VaultIndicator__exact=True).filter(CircuitNumber__gte=LowNumber).filter(CircuitNumber__lte=HighNumber).count()
        else:
            Vaults=Vaults.exclude(CircuitNumber__gte=LowNumber, CircuitNumber__lte=HighNumber)
        if(Include):
            PadMountTransformers=Assembly.objects.filter(CompatibleUnit__TransformerIndicator__exact=True).filter(CompatibleUnit__NormallyUndergroundIndicator=True).filter(CircuitNumber__gte=LowNumber).filter(CircuitNumber__lte=HighNumber).count()
            TotalPadMountTransformers=TotalPadMountTransformers + PadMountTransformers
        else:
            PadMountTransformers=PadMountTransformers.exclude(CircuitNumber__gte=LowNumber, CircuitNumber__lte=HighNumber)
       
        VaultsToSubtract=0 
        if(Include):
            Vaults=Assembly.objects.filter(CompatibleUnit__VaultIndicator__exact=True).filter(CircuitNumber__gte=LowNumber).filter(CircuitNumber__lte=HighNumber)
            for i in Vaults:
                if(Include and Assembly.objects.filter(Station=i.Station).filter(CompatibleUnit__PoleIndicator=True)):
                    VaultsToSubtract = VaultsToSubtract + 1
            VaultsTotal=VaultsTotal + TotalVaults - VaultsToSubtract
    if(not Include):
        TotalPoles=Poles.count()
        TotalMeters=Meters.count()
        VaultsToSubtract=0
        for i in Vaults:
            if(Assembly.objects.filter(Station=i.Station).filter(CompatibleUnit__PoleIndicator=True)):
                VaultsToSubtract = VaultsToSubtract + 1
        VaultsTotal=Vaults.count()-VaultsToSubtract
        TotalPadMountTransformers=PadMountTransformers.count()
    return str(TotalPoles), str(TotalMeters), str(VaultsTotal), str(TotalPadMountTransformers)



def BuildChangePasswordForm():
    Dict={}
    Dict['OldPassword']=forms.CharField(label='Old Password:  ', max_length = 255, widget=forms.PasswordInput)
    Dict['NewPassword']=forms.CharField(label='New Password:  ', max_length = 255, widget=forms.PasswordInput)
    Dict['NewPasswordVerify']=forms.CharField(label='New Password (again):  ', max_length = 255, widget=forms.PasswordInput)
    return Dict

class LoginForm(forms.Form):
    UserName=forms.CharField(label='User Name:')
    Password=forms.CharField(widget=forms.PasswordInput)




def ConfigureBluetooth(request):
    if request.method == 'POST':
        MACAddress = request.POST['MACAddress']
        form=ConfigureBluetoothForm(request.POST)
        UpdateBluetoothMasterFile(MACAddress)
        MACAddress=COOPGIS_Update.ReadBlueToothMasterFile()
        COOPGIS_Update.CreateConnectToBluetoothScript(MACAddress)
    else:
        form=ConfigureBluetoothForm()
    HCIToolScanResult=GetHCIToolScanResult()
    t=loader.get_template('/opt/coopgis/djangoproject/templates/configurebluetooth.html')
    c=Context({'form': form, 'HCIToolScanResult': HCIToolScanResult})
    return HttpResponse(t.render(c))




class ConfigureBluetoothForm(forms.Form):
    MACAddress=forms.CharField(label='Bluetooth MACAddress:')
 
def GetHCIToolScanResult():
    FileName=djangoproject.settings.COOPGISHCIToolScanResultFile 
    try:
        os.remove(FileName)
    except:
        pass
    os.system('sudo -u apachescript sudo hcitool scan > '+ FileName)
    File=open(FileName, 'r')
    Results=File.readlines()
    File.close()
    return ''.join(Results) 
    
def UpdateBluetoothMasterFile(MACAddress):
    FileName=djangoproject.settings.COOPGISBlueToothMacAddressFileName
    if(not MACAddress):
        return
    try:
        os.remove(FileName)
    except:
        pass
    File=open(FileName, 'w')
    File.write(MACAddress)
    File.close()




def GPSTrace(request):
    ApplicationName=djangoproject.settings.COOPGISViewerApplicationName
    UserNameOrIPAddress, DefaultMap=COOPGIS_Misc.GetUserNameOrIPAddress(request, GetDefaultMap=True, ApplicationName=ApplicationName)
    form=COOPGIS_FormMisc.BuildForm(request, ApplicationName, DefaultMap)
    COOPGIS_FormGeography.GetAndSetDefaultMap(form, ApplicationName, UserNameOrIPAddress)
    SelectionStation, SelectionSpan, GPSStatus = COOPGIS_FormGeography.SetSelectionStationAndSpan(form)
    OpenLayersZoom=COOPGIS_Ajax.GetOpenLayersZoom(SelectionStation, SelectionSpan, 14)
    MapFileName, LayerName =COOPGIS_Misc.GenerateDynamicMapFile(ApplicationName, UserNameOrIPAddress) 
    COOPGIS_Misc.UpdateSelection(SelectionStation, SelectionSpan, UserNameOrIPAddress)
    t = loader.get_template('/opt/coopgis/djangoproject/templates/gpstrace.html')
    c = Context({'OpenLayersZoom': OpenLayersZoom, 'form': form,
                 'MapFileName': MapFileName, 'LayerName':LayerName})
    return HttpResponse(t.render(c))



def DevelopmentTest(request):
    import django.db
    GenericReportTitle='COOPGIS DevelopmentTest'
    GenericMessage='This page is used during COOPGIS Development.  Not Intended for Production Use.'
    ApplicationName=djangoproject.settings.COOPGISCISApplicationName
    UserNameOrIPAddress=COOPGIS_Misc.GetUserNameOrIPAddress(request, GetDefaultMap=False, ApplicationName=ApplicationName)
    LoginStatus, applicationPermission=COOPGIS_Misc.CheckLoginPermissions(request, ApplicationName)
    StringList=[]
    #*************************************START TEST CODE****************************************


    #import datetime
    #startdate=datetime.datetime.today() - datetime.timedelta(days=23)
    #raise(Exception(str(startdate)))
    #meter=Assembly.objects.filter(MeterNumber='5393776')[0]



    #*************************************END TEST CODE****************************************
    Preformatted='\n'.join(StringList)
    #End Data Gathering Tasks
    t = loader.get_template('/opt/coopgis/djangoproject/templates/genericreporttemplate.html')
    c = Context({'LoginStatus' : LoginStatus, 'Preformatted': Preformatted, 'GenericReportTitle': GenericReportTitle,
                 'GenericMessage': GenericMessage})
    return HttpResponse(t.render(c))



def RebuildSpecifiedSymbology(request, Number):
    try:
        id = int(Number)
    except IOError:
        return HttpResponse('Failed\n')

    Success=False
    try:
        station=djangoproject.models.geography.Station.objects.filter(id=id)[0]         
        station.RebuildSymbology()
        Success=True
    except:
        pass
    try:
        span=djangoproject.models.geography.Span.objects.filter(id=id)[0]         
        span.RebuildSymbology()
        Success=True
    except:
         pass
    if(Success):
        return HttpResponse('Succeeded\n')
    return HttpResponse('Failed\n')

